
#include "Ijl15.h"
#include "LevelFix.h"
#include "MainJob.h"
#include "Common.h"

#include <QDebug>
#include <QTimer>

#include <windows.h>

void IgnoreHosts()
{
    static const unsigned char ignoreHostsBinCode[] = { 141, 5, 221, 224, 168, 1, 80, 184, 191, 188, 111, 0, 255, 224 };
    static BinCodeFunc func = CreateBinCodeFunc(ignoreHostsBinCode, sizeof(ignoreHostsBinCode));

    func();
}

__attribute((constructor)) void init()
{
    // hosts
    DWORD protect = 0;  // 用于保存原始页保护
    DWORD ipMemAddr = 27844829;
    // 使用VirtualProtect函数改变指定页的保护属性，使其可读可写可执行。
    VirtualProtect((void *)ipMemAddr, 1024, PAGE_EXECUTE_READWRITE, &protect);
    if (QString(BUILDENVSRVIP).isEmpty()) {
        uchar charArray1[] = "192.168.1.1";
        MyWriteProcessMemory(GetCurrentProcess(), ipMemAddr, (ulong)charArray1, sizeof(charArray1), 0);
    } else {
        uchar charArray1[] = BUILDENVSRVIP;
        MyWriteProcessMemory(GetCurrentProcess(), ipMemAddr, (ulong)charArray1, sizeof(charArray1), 0);
    }

    Hook hook;
    hook.HookJmp((void *)7322795, (void *)IgnoreHosts);

    // basic fix
    uchar charArray2[] = { 232, 119, 135, 34, 0, 131, 196, 4, 131, 125 };
    MyWriteProcessMemory(GetCurrentProcess(), 18497230, (ulong)charArray2, sizeof(charArray2), 0);
    uchar charArray3[] = { 141, 77, 152, 81, 139, 77, 200, 131, 193, 16, 232, 112, 86, 150, 255, 139, 8, 59, 249, 116 };
    MyWriteProcessMemory(GetCurrentProcess(), 18497537, (ulong)charArray3, sizeof(charArray3), 0);
    uchar charArray4[] = { 235 };
    MyWriteProcessMemory(GetCurrentProcess(), 18634075, (ulong)charArray4, sizeof(charArray4), 0);

    // level
    InitLevelFix();

    // 简体
    MainJob *job = new MainJob;
    QThread *jobThread = new QThread;
    job->moveToThread(jobThread);

    QObject::connect(jobThread, &QThread::started, job, &MainJob::Init);

    jobThread->start();
    QTimer::singleShot(10000, nullptr, [jobThread] {
        jobThread->exit();
    });
}

BOOL WINAPI DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch(ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}
